# coding=utf-8

import web
import utils

class AdminSession(object):
    '''
    表示一个管理员登录会话
    '''
    # cookie名
    COOKIE_NAME = '_s_'

    def __init__(self):
        self.id = 0
        self.name = None
        self.init()

    def init(self):
        '''
        执行初始化
        包括获取cookie原文并重新组织
        '''
        # 从cookie中获取的是密文
        # 此处需要解密
        sid = utils.decrypt(web.cookies().get(AdminSession.COOKIE_NAME, False))

        # 解密失败或cookie中获取的None
        # 那么都认为是未登录
        if not sid:
            return

        vals = sid.split('|')
        # 值的格式不正确
        if len(vals) != 2:
            return

        try:
            self.id = int(vals[0])
        except:
            self.id = 0

        self.name = vals[1]

    def is_auth(self):
        '''
        当前管理会话实例是否已通过验证
        '''
        return self.id > 0 and self.name

    @staticmethod
    def save_state(id, name):
        '''
        保存登录状态
        @id as int, 管理员内码
        @name as string, 管理员名称
        '''
        if id <= 0 or not name:
            return False

        # 写入cookie
        web.setcookie(AdminSession.COOKIE_NAME, utils.encrypt('%d|%s' % (id, name)))
        # 这里就简单的加密一下
        # 必要的时候，可以加上数字签名
        return True

    @staticmethod
    def logout(redir = '/login'):
        '''
        退出登录
        @redir as string, 退出后，返回的页面，默认为登录页
        '''
        web.setcookie(AdminSession.COOKIE_NAME, None)
        if redir:
            # 转向到指定页
            raise web.seeother(redir)

    @staticmethod
    def current():
        '''
        获取当前登录会话的管理员实例
        '''
        return AdminSession()

def auth_login(func):
    '''
    验证登录状态的装饰器，用到管理后台视图中
    '''
    def proxy(iself, *args, **kw):
        session = AdminSession.current()
        if session.is_auth():
            return func(iself, *args, **kw)
        else:
            # 无效登录
            #return AdminSession.logout()
            # 因为后台是采用的框架结构
            # 因此在无效登录进行跳转时，使用得JS跳转
            return '<script type="text/javascript">top.location.href="/admin/login";</script>'
    return proxy
